package com.hyjiacan.apps.audionly.ui.viewmodel

import android.app.Application
import android.os.AsyncTask
import android.os.Environment
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.hyjiacan.apps.audionly.data.model.AudioParam
import com.hyjiacan.apps.audionly.data.model.TaskInfo
import com.hyjiacan.apps.audionly.data.model.VideoFile
import com.hyjiacan.apps.audionly.data.repository.TaskRepositoryImpl
import com.hyjiacan.apps.audionly.utils.ExoAudioExtractor
import kotlinx.coroutines.launch
import java.io.File
import java.util.*

/**
 * 提取进度界面的ViewModel
 */
class ExtractViewModel(application: Application) : AndroidViewModel(application) {
    // 提取状态枚举
    enum class Status {
        IDLE, EXTRACTING, COMPLETED, FAILED
    }

    // 提取进度 LiveData
    private val _progress = MutableLiveData<Int>(0)
    val progress: LiveData<Int> = _progress

    // 进度文本 LiveData
    private val _progressText = MutableLiveData<String>("0%")
    val progressText: LiveData<String> = _progressText

    // 状态文本 LiveData
    private val _statusText = MutableLiveData<String>("准备提取")
    val statusText: LiveData<String> = _statusText

    // 提取状态 LiveData
    private val _extractStatus = MutableLiveData<Status>(Status.IDLE)
    val extractStatus: LiveData<Status> = _extractStatus

    // 错误信息
    var errorMessage: String = ""

    // 输出文件路径
    var outputFilePath: String = ""

    // 自定义存储路径
    private var customStoragePath: String? = null

    // 任务仓库
    private val taskRepository = TaskRepositoryImpl()

    // 音频提取器
    private val audioExtractor = ExoAudioExtractor(getApplication())

    /**
     * 开始提取音频
     */
    fun startExtract(
        videoPath: String,
        outputFilename: String,
        bitrate: Int,
        customStoragePath: String? = null,
        format: String
    ): String {
        // 检查是否有自定义存储路径
        if (customStoragePath != null) {
            // 使用自定义存储路径
            this.customStoragePath = customStoragePath
        } else {
            // 默认使用应用私有数据目录
            this.customStoragePath = getApplication<Application>().getExternalFilesDir(null)?.absolutePath
            // 如果为 null，表示存储不可用，应用无法工作
            if (this.customStoragePath == null) {
                // 给用户提示
                errorMessage = "存储不可用"
                throw IllegalStateException("存储不可用")
            }
        }

        // 创建音频参数
        val audioParam = AudioParam(format = format, bitRate = bitrate)

        // 创建TaskInfo对象
        val taskInfo = TaskInfo(
            id = UUID.randomUUID().toString(),
            videoFile = VideoFile(
                id = UUID.randomUUID().toString(),
                name = File(videoPath).name,
                path = videoPath,
                duration = 0, // 实际应用中需要获取视频时长
                size = File(videoPath).length(),
                format = File(videoPath).extension
            ),
            audioParam = audioParam,
            status = TaskInfo.Status.PROCESSING,
            createTime = Date(),
            startTime = Date()
        )
        // 在协程中插入任务
        viewModelScope.launch {
            taskRepository.insertTask(taskInfo)
        }

        // 更新状态
        _extractStatus.value = Status.EXTRACTING
        _statusText.value = "开始提取音频..."

        // 在后台线程执行提取
        ExtractTask(taskInfo).execute(videoPath, outputFilename, bitrate.toString(), format)

        return taskInfo.id
    }

    /**
     * 提取音频的异步任务
     */
    private inner class ExtractTask(private val taskInfo: TaskInfo) : AsyncTask<String, Int, Boolean>() {
        override fun doInBackground(vararg params: String): Boolean {
            val videoPath = params[0]
            val outputFilename = params[1]
            val bitrate = params[2].toInt()
            val format = params[3]

            try {
                // 确定输出目录
                var outputDir: File = File(customStoragePath, "output")
                
                // 确保目录存在
                if (!outputDir.exists()) {
                    outputDir.mkdirs()
                }
                // 确保文件名不包含扩展名，避免重复添加
val filenameWithoutExtension = outputFilename.substringBeforeLast('.', outputFilename)
val outputFile = File(outputDir, "$filenameWithoutExtension.${taskInfo.audioParam.format.lowercase()}")
                outputFilePath = outputFile.absolutePath

                // 执行提取
                // 根据用户需求，默认提取格式调整为WAV
                
                // 映射音频格式到OutputFormat枚举
                val outputFormat = when (taskInfo.audioParam.format.lowercase()) {
                    "aac" -> ExoAudioExtractor.OutputFormat.AAC
                    "mp3" -> ExoAudioExtractor.OutputFormat.MP3
                    "wav" -> ExoAudioExtractor.OutputFormat.WAV
                    "flac" -> ExoAudioExtractor.OutputFormat.FLAC
                    "ogg" -> ExoAudioExtractor.OutputFormat.OGG
                    "m4a" -> ExoAudioExtractor.OutputFormat.M4A
                    else -> ExoAudioExtractor.OutputFormat.MP3 // 默认值
                }

                audioExtractor.extractAudio(
                    inputPath = videoPath,
                    outputDir = outputDir.absolutePath,
                    outputFormat = outputFormat,
                    scope = viewModelScope,
                    progressListener = {
                        progress ->
                        publishProgress(progress)
                    },
                    completionListener = { success, message ->
                        if (success) {
                            // 提取成功，文件路径已在outputFilePath中
                        } else {
                            errorMessage = message
                        }
                    }
                )

                // 在协程中更新任务状态为完成
                viewModelScope.launch {
                    val updatedTask = taskInfo.copy(
                        status = TaskInfo.Status.COMPLETED,
                        endTime = Date(),
                        outputPath = outputFile.absolutePath
                    )
                    taskRepository.updateTask(updatedTask)
                }
                return true
            } catch (e: Exception) {
                errorMessage = e.message ?: "提取失败"
                // 在协程中更新任务状态为失败
                viewModelScope.launch {
                    val updatedTask = taskInfo.copy(
                        status = TaskInfo.Status.FAILED,
                        endTime = Date(),
                        outputPath = errorMessage
                    )
                    taskRepository.updateTask(updatedTask)
                }
                return false
            }
        }

        override fun onProgressUpdate(vararg values: Int?) {
            values[0]?.let {
                _progress.value = it
                _progressText.value = "${it}%"
            }
        }

        override fun onPostExecute(result: Boolean) {
            if (result) {
                _extractStatus.value = com.hyjiacan.apps.audionly.ui.viewmodel.ExtractViewModel.Status.COMPLETED
                _statusText.value = "提取完成"
            } else {
                _extractStatus.value = com.hyjiacan.apps.audionly.ui.viewmodel.ExtractViewModel.Status.FAILED
                _statusText.value = errorMessage
            }
        }
    }
}